package nku.csc364;

import java.util.*;
import java.io.*;

/* PriorityQueue.java
 * Raj Kiran Akula
 * CSC 364	
 * 
 * A generic Priority Queue class, that has x amount of priorities that 
 * the user can specify. Uses a linked list on the back end to support
 * the queues.
 *
 */
@SuppressWarnings("rawtypes")
public class PriorityQueue{
 	private int numOfPriorities; // Number of Priorities
 	private LinkedList list; // List of Queues
 	
 	
 	//Constructor with one argument... the number of priorities
 	@SuppressWarnings("unchecked")
	public PriorityQueue(int numPriorities){
 		
 		this.numOfPriorities = numPriorities; //Instantiating data field
 		list = new LinkedList(); // Creating linked list for the different queues
 		
 		//Loop to instantiate no of queues using numOfPriorities
		for (int i = 0; i < numPriorities; i++){
			list.add(new LinkedList()); 
		}
		System.out.println("Queues have been Initilized !!!");
 		
 	}
 	
 	// Method that gets the size of the priority queue
 	public int size() {
		
		int size = 0; //temp total size variable to keep track of size
		
		//Gets size of each priority and adds it to running total of size
		for (int i = 0; i < numOfPriorities; i++){
			LinkedList q = (LinkedList)list.get(i);
			size = size + q.size();
		}
		
		return size; 
	}
 	
 	//Method to add patients to a specific priority queue
 	@SuppressWarnings("unchecked")
	public void enqueue(String name, int priority, String date) throws IOException{
 		
 		//Get the priority queue in question
 		LinkedList q = (LinkedList)list.get(priority-1);
 		
 		//Add it to that queue
		q.addLast(new Patient(name, priority, date));
		
		//This is called to save current queue.. in case of a crash... 
		saveToFile();
 	}
 	
 	public Patient dequeue()throws IOException{
 		
 		Patient returnPatient = null; //Temporary object for dequeue patient
 		
 		//Loop used to iterate through the priorities in order and 
 		// to dequeue the first patient with highest priority
		for (int i = 0; i < numOfPriorities; i++){
			LinkedList q = (LinkedList)list.get(i);
			if(!q.isEmpty()){
				
				//If a person is dequeued the remove him from the list 
				//and save a new copy of the current queue
				returnPatient = (Patient)q.removeFirst();
				saveToFile();
				break;
			}
		}
		
		//If no one in queue to be dequeued then pops a message
		if (returnPatient == null){
			System.out.println("No one in queue in any level!!!");
			return null;
		}
		//Otherwise it returns the patients info and returns the patient 
		//to client if he needs to do anything with it... 
		else{
			System.out.println(returnPatient);
			return returnPatient;
		}
 	}
 	
 	
 	//Checks to see if anything is in the priority queue
 	public boolean isEmpty() {
		
		//Loops through each priority to check if its empty
		for (int i = 0; i < numOfPriorities; i++){
			LinkedList q = (LinkedList)list.get(i);
			if(!q.isEmpty()){
				return false;// if it finds something then returns false
			}
		}
		
		//Here it looped throught everything and hasn't found anything so returns true.
		return true;
	}
 	
 	//Spits out all patients in priority one and if none, gives message accordingly
 	public void priorityOneDump(){
 		
 		//Gets first queue -> in correspondance to first priority queue
 		LinkedList q = (LinkedList)list.get(0);
 		
 		//Checks if its empty if it is then display appropriate message
 		if(q.isEmpty()){
 			System.out.println("There are no patients that have Priority Status 1!!!");
 			return;
 		}
 		
 		//Otherwise it iterates through displaying all the patients there are...
 		//Used an iterator to iterate through the priority one list.
 		ListIterator itr = q.listIterator(); 
 		while(itr.hasNext())
    	{
    	  System.out.println(itr.next());
   	 	}
 	}
 	
 	//Method that goes through each priority and saves the patients info
	public void saveToFile()throws IOException{
		
		//Code to write to file
		FileOutputStream fo = new FileOutputStream("backup.txt");
		PrintStream ps = new PrintStream(fo);
		
		//Writing no. of priorities for reinitlizing the queue
        ps.println(numOfPriorities);
        
        //Code to loop thorugh all the priorities to save all the patients info.
        //Again used an iterator to do this!!!
		for(int i = 0; i < numOfPriorities; i++){
			LinkedList q = (LinkedList)list.get(i);
			ListIterator itr = q.listIterator();
 			while(itr.hasNext())
    		{
    		  	ps.println(itr.next().toString());
   	 		}
		}
	}
 }